package com.xm.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.xm.context.BaseContext;
import com.xm.domain.dto.DishDTO;
import com.xm.domain.dto.DishPageQueryDTO;
import com.xm.domain.po.Dish;
import com.xm.domain.po.DishFlavor;
import com.xm.domain.po.Employee;
import com.xm.domain.po.SetmealDish;
import com.xm.domain.vo.DishVO;
import com.xm.exception.BaseException;
import com.xm.mapper.DishFlavorMapper;
import com.xm.mapper.DishMapper;
import com.xm.result.PageResult;
import com.xm.service.DishService;
import com.xm.utils.BeanUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜品 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    private final  DishFlavorMapper dishFlavorMapper;


    @Transactional
    @Override
    public void saveWithFlavor(DishDTO dishDTO) {

        // 1补充属性
        Dish dish = BeanUtils.copyBean(dishDTO, Dish.class);
        //1.1 拿到当前商家id,去找到店铺
        Long currentId = BaseContext.getCurrentId();
        Employee employee = Db.lambdaQuery(Employee.class).eq(Employee::getId, currentId).one();
        String shopId = employee.getShopId();

        dish.setShopId(shopId);
        dish.setCreateUser(currentId);
        dish.setUpdateUser(currentId);
        dish.setStatus(1);
        dish.setCreateTime(LocalDateTime.now());
        dish.setUpdateTime(LocalDateTime.now());
        // 2 插入菜品数据
        save(dish);

        // 3添加口味数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        flavors.forEach(flavor -> {
            flavor.setDishId(dish.getId());
        });
        Db.saveBatch(flavors);

    }

    @Override
    public PageResult<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO) {
        //1构建分页条件
        //1.1 分页条件
        Page<Dish> page = Page.of(dishPageQueryDTO.getPageNo(), dishPageQueryDTO.getPageSize());
        //1.2 排序条件 基本默认根据修改时间降序
        page.addOrder( OrderItem.desc("update_time"));

        //2.分页查询
        //2.1 拿到当前商家id,去找到店铺

        Long currentId = BaseContext.getCurrentId();
        Employee employee = Db.lambdaQuery(Employee.class).eq(Employee::getId, currentId).one();
        String shopId = employee.getShopId();

        Page<Dish> p= lambdaQuery()
                .like(dishPageQueryDTO.getName() != null, Dish::getName, dishPageQueryDTO.getName())
                .eq(dishPageQueryDTO.getStatus() != null, Dish::getStatus, dishPageQueryDTO.getStatus())
                .eq(dishPageQueryDTO.getCategoryId() != null, Dish::getCategoryId, dishPageQueryDTO.getCategoryId())
                .eq(Dish::getShopId,shopId)
                .page(page);
        //3封装PageResult结果
        PageResult<DishVO> pageResult = new PageResult<>();
        //3.1 总条数
        pageResult.setTotal(   page.getTotal());

        //3.2 总页数
        pageResult.setPages(page.getSize());
        //3.3 数据
        List<Dish> records = p.getRecords();
        if (CollUtil.isEmpty(records)){
            pageResult.setList(Collections.emptyList());
        }
        //将数据放到封装口味方法
        List<DishVO> dishVOS = dishWithFlavor(records);
        pageResult.setList(dishVOS);
        return pageResult;
    }

    @Override
    @Transactional
    public void deleteBatch(List<Long> ids) {
        // 1 删除数据
        if (CollUtil.isEmpty(ids)){
            log.info("删除数据异常");

        }

        //1.判断当前菜品是否能够删除---是否存在起售中的菜品??
//        根据菜品id和status=1 统计查出来的数量 如果结果是大于0，那就证明了还有菜品在起售中，

        List<Dish> list = lambdaQuery().in(Dish::getId, ids).eq(Dish::getStatus, "1").list();
        log.info("次数:{}+{}",list.size());
        if (list.size()>0){
            //当前菜品处于起售中，不能删除
            throw new BaseException("当前菜品中还有处于起售中，不能删除");
        }


        //2.判断当前菜品是否能够删除---是否被套餐关联了?? 根据菜品id查询关联表的数据条数，如果结果大于0，就是不能删除了

        List<SetmealDish> list1 = Db.lambdaQuery(SetmealDish.class).in(SetmealDish::getDishId, ids).list();
        log.info("setmealIds:{}",list1 );
        if (list1.size()>0){
            //当前菜品被套餐关联了，不能删除
            throw new BaseException("当前菜品被套餐关联了，不能删除");

        }

        //删除菜品表中的菜品数据
        removeBatchByIds(ids);

        //删除菜品关联的口味数据
        dishFlavorMapper.deleteByDishIds(ids);

    }

    @Override
    public DishVO getByIdWithFlavor(Long id) {
        List<Dish> list = lambdaQuery().eq(Dish::getId, id).list();
        log.info("{}",list.toString());
        List<DishVO> dishVOS = dishWithFlavor(list);

        return dishVOS.get(0);
    }
    /**
     * 封装口味方法
     */
    public  List<DishVO>  dishWithFlavor(List<Dish> records){
        // 封装 口味
        List<DishVO> dishVOS = BeanUtils.copyList(records, DishVO.class);

        List<String>  dishIds= records.stream().map(Dish::getId).collect(Collectors.toList());
        List<DishFlavor> dishFlavors;
        dishFlavors = Db.lambdaQuery(DishFlavor.class).in(DishFlavor::getDishId, dishIds).list();
          //当口味为空
        if (CollUtil.isEmpty(dishFlavors)){
            dishVOS.forEach(dishVO -> dishVO.setFlavors(Collections.emptyList()));
          return dishVOS;
        }

        Map<String, List<DishFlavor>> map = dishFlavors.stream().collect(Collectors.groupingBy(DishFlavor::getDishId));
        dishVOS.forEach(dishVO -> {
            List<DishFlavor> dishFlavors1 = map.get(dishVO.getId().toString());
            dishVO.setFlavors(dishFlavors1);
        });

        return dishVOS;
    }


    @Override
    public void updateWithFlavor(DishDTO dishDTO) {
        // 1补充属性
        Dish dish = BeanUtils.copyBean(dishDTO, Dish.class);
        //1.1 拿到当前商家id
        Long currentId = BaseContext.getCurrentId();
        Employee employee = Db.lambdaQuery(Employee.class).eq(Employee::getId, currentId).one();

        dish.setUpdateUser(currentId);
        dish.setUpdateTime(LocalDateTime.now());

        // 2 插入菜品数据
      updateById(dish);

        // 3修改口味数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        flavors.forEach(flavor -> {
            flavor.setDishId(dish.getId());
        });
        Db.updateBatchById(flavors);

    }

    @Override
    public List<DishVO> getDishByCategoryId(Long categoryId) {

        List<DishVO> listVos;
        // 根据分类id查询菜品
        List<Dish> list = lambdaQuery().eq(Dish::getCategoryId, categoryId).list();
        if (CollUtil.isEmpty(list)){
            return listVos=new ArrayList<>();
        }
        // 将查到的菜品数据去装他们的口味数据
        listVos=dishWithFlavor(list);


        return listVos;
    }
}
